/*

This file is part of Rooms3D.

Copyright (C) 2008 Pixecur Technologies Incorporated (Esotera).
Visit Esotera at http://www.esoteras3.com
 
Rooms3D is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
 
Rooms3D is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with Rooms3D; see the file COPYING.  If not, write to 
Pixecur Technologies, 213-31 Peet Street, St. John's, NL, A1B 3W8. 
 
Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
 
*/

package com.datasentinel.j3d.controls.hud;

import java.awt.Color;
import java.awt.Font;
import java.awt.SystemColor;

import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Material;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.TransparencyAttributes;
import javax.vecmath.Color3f;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

import com.datasentinel.j3d.controls.J3DComponent;
import com.datasentinel.j3d.controls.J3DComponentUI;
import com.datasentinel.j3d.controls.J3DUIHelper;
import com.datasentinel.j3d.utils.geometry.MutableText2D;
import com.sun.j3d.utils.geometry.Box;

public class HeadsUpDisplayUI extends J3DComponentUI
{

	/**
	 * Swing/AWT utility class instances
	 */
	
	private Color topFrameBoxColor;
	private Color currentAddressBoxColor;
	private Color transferProgressBoxColor;
	private Color clipboardBoxColor;
	
	private Color currentAddressTextColor;
	private Font currentAddressTextFont;

	private Color currentFileTextColor;
	private Font currentFileTextFont;
	
	/**
	 * Controls and primitives
	 */
	private Box topFrameBox;

	private Box currentAddressBox;
	private Box transferProgressBox;
	private Box clipboardBox;

	private MutableText2D currentAddressText2D;
	
	private MutableText2D currentFileText2D;
	
	private BranchGroup progressBarBrnchGrp;
	private BranchGroup cancelButtonBrnchGrp;
	
	private BranchGroup currentFileTextBrnchGrp;
	/**
	 * Appearance, materials, attributes
	 */

	private Material topFrameBoxMaterial;
	private Appearance topFrameBoxAppearance;
	private TransparencyAttributes topFrameBoxTransparencyAttribs;


	private Material currentAddressBoxMaterial;
	private Appearance currentAddressBoxAppearance;


	private Material transferProgressBoxMaterial;
	private Appearance transferProgressBoxAppearance;

	private Material clipboardBoxMaterial;
	private Appearance clipboardBoxAppearance;


	/**
	 * Transformation related fields
	 */

	private Transform3D topFrameTranslateT3D;
	private Transform3D topFrameRotateT3D;
	private Transform3D topFrameScaleT3D;
	
	private Transform3D transferProgressBoxTranslateT3D;
	
	private Transform3D progressBarRotateT3D;
	private Transform3D progressBarScaleT3D;
	private Transform3D progressBarTranslateT3D;

	private Transform3D cancelButtonRotateT3D;
	private Transform3D cancelButtonScaleT3D;
	private Transform3D cancelButtonTranslateT3D;
	
	private Transform3D clipboardBoxTranslateT3D;

	private Transform3D currentAddressBoxTranslateT3D;
	private Transform3D currentAddressTextScaleT3D;
	private Transform3D currentAddressTextTranslateT3D;

	private Transform3D currentFileTextTranslateT3D;
	private Transform3D currentFileTextScaleT3D;

	private TransformGroup topFrameTranslateTrnsGrp;
	private TransformGroup topFrameRotateTrnsGrp;
	private TransformGroup topFrameScaleTrnsGrp;


	private TransformGroup currentAddressBoxTranslateTrnsGrp;
	private TransformGroup currentAddressTextScaleTrnsGrp;
	private TransformGroup currentAddressTextTranslateTrnsGrp;

	private TransformGroup currentFileTextScaleTrnsGrp;
	private TransformGroup currentFileTextTranslateTrnsGrp;
	
	private TransformGroup transferProgressBoxTranslateTrnsGrp;
	

	private TransformGroup cancelButtonRotateTrnsGrp;
	private TransformGroup cancelButtonScaleTrnsGrp;
	private TransformGroup cancelButtonTranslateTrnsGrp;

	
	private TransformGroup progressBarRotateTrnsGrp;
	private TransformGroup progressBarScaleTrnsGrp;
	private TransformGroup progressBarTranslateTrnsGrp;

	private TransformGroup clipboardBoxTranslateTrnsGrp;


	@Override
	protected void initializeComponentParts()
	{

		topFrameBoxColor = Color.WHITE;
		
		topFrameBoxMaterial = new Material();
		topFrameBoxMaterial.setDiffuseColor(new Color3f(topFrameBoxColor));
		
		topFrameBoxTransparencyAttribs = new TransparencyAttributes();
		topFrameBoxTransparencyAttribs
				.setTransparencyMode(TransparencyAttributes.BLENDED);
		// topFrameBoxTransparencyAttribs.setSrcBlendFunction(
		// TransparencyAttributes.BLEND_ZERO);
//		topFrameBoxTransparencyAttribs
//				.setDstBlendFunction(TransparencyAttributes.BLEND_SRC_ALPHA);
		
		topFrameBoxTransparencyAttribs.setTransparency(0.5f);
		topFrameBoxAppearance = new Appearance();
		topFrameBoxAppearance.setMaterial(topFrameBoxMaterial);
		topFrameBoxAppearance
				.setTransparencyAttributes(topFrameBoxTransparencyAttribs);
		topFrameBox = new Box(7.0f, 1.0f, 0.2f, topFrameBoxAppearance);


		
		
		currentAddressBoxColor = Color.GREEN.brighter();
		currentAddressBoxMaterial = (Material)topFrameBoxMaterial.cloneNodeComponent(true);
		currentAddressBoxMaterial.setDiffuseColor(new Color3f(currentAddressBoxColor));
		currentAddressBoxAppearance = (Appearance)topFrameBoxAppearance.cloneNodeComponent(true);
		currentAddressBoxAppearance.setMaterial(currentAddressBoxMaterial);
//		currentAddressBoxAppearance.getTransparencyAttributes().setTransparency(0.0f);
		currentAddressBox = new Box(4.0f, 0.2f, topFrameBox.getZdimension(),
				currentAddressBoxAppearance);

		transferProgressBoxColor = Color.CYAN.darker();
		transferProgressBoxMaterial = (Material)topFrameBoxMaterial.cloneNodeComponent(true);
		transferProgressBoxMaterial.setDiffuseColor(new Color3f(transferProgressBoxColor));
		transferProgressBoxAppearance = (Appearance)topFrameBoxAppearance.cloneNodeComponent(true);
		transferProgressBoxAppearance.setMaterial(transferProgressBoxMaterial);
		transferProgressBox = new Box(4.0f, 0.79f, topFrameBox.getZdimension(),
				transferProgressBoxAppearance);

		clipboardBoxColor = topFrameBoxColor;
		clipboardBoxMaterial = (Material)topFrameBoxMaterial.cloneNodeComponent(true);
		clipboardBoxMaterial.setDiffuseColor(new Color3f(clipboardBoxColor));
		clipboardBoxAppearance = (Appearance)topFrameBoxAppearance.cloneNodeComponent(true);
		clipboardBoxAppearance.setMaterial(clipboardBoxMaterial);
		clipboardBox = new Box(1.0f, 1.0f, topFrameBox.getZdimension(), clipboardBoxAppearance);


		currentAddressTextColor = SystemColor.BLACK;
		currentAddressTextFont = new Font(Font.SANS_SERIF, Font.BOLD, 25);

		currentAddressText2D = new MutableText2D("", new Color3f(
				currentAddressTextColor), currentAddressTextFont.getName(),
				currentAddressTextFont.getSize(), currentAddressTextFont
						.getStyle());
		

		currentFileTextBrnchGrp = new BranchGroup();
		currentFileTextBrnchGrp.setCapability(BranchGroup.ALLOW_DETACH);
		
		currentFileTextColor = SystemColor.BLACK;
		currentFileTextFont =  new Font(Font.SANS_SERIF, Font.BOLD, 25);
		
		currentFileText2D = new MutableText2D("", new Color3f(
				currentFileTextColor), currentFileTextFont.getName(),
				currentFileTextFont.getSize(), currentFileTextFont
						.getStyle());
		
//		TextureAttributes currentAddressTextureAtts;
//		currentAddressTextureAtts = new TextureAttributes();
		
//		currentAddressTextureAtts.setTextureMode(TextureAttributes.BLEND);
//		currentAddressText2D.getAppearance().setTextureAttributes(currentAddressTextureAtts);
		
		
//		currentAddressText2D.getAppearance().setTransparencyAttributes((TransparencyAttributes)topFrameBoxTransparencyAttribs.cloneNodeComponent(false));
//		currentAddressText2D.getAppearance().getTransparencyAttributes().setSrcBlendFunction(TransparencyAttributes.BLEND_DST_COLOR);
//		Material currentAddressText2DMaterial;
//		Appearance currentAddressText2DAppearance;
		
//		currentAddressText2DMaterial = new Material();
//		currentAddressText2DMaterial.setEmissiveColor(new Color3f(currentAddressTextColor));
//		currentAddressText2DAppearance = new Appearance();
//		currentAddressText2DAppearance.setMaterial(currentAddressText2DMaterial);
//		currentAddressText2D.getAppearance().setMaterial(currentAddressText2DMaterial);
//		.setAppearance(currentAddressText2DAppearance);
		

	}

	@Override
	protected void initializeComponentPartsLayout()
	{
		initializeTopFrameLayout();
		initializeAddressFrameLayout();
		initializeTransferProgressFrameLayout();
		initializeClipboardFrameLayout();
	}

	private void initializeTopFrameLayout()
	{

		topFrameTranslateT3D = new Transform3D();
		topFrameRotateT3D = new Transform3D();
		topFrameScaleT3D = new Transform3D();
		
		topFrameTranslateT3D.setTranslation(new Vector3f(0, -4, -12.5f));
//		topFrameRotateT3D.rotX(Math.PI / 4.0);

		
		topFrameTranslateTrnsGrp = new TransformGroup(topFrameTranslateT3D);
		topFrameScaleTrnsGrp = new TransformGroup(topFrameScaleT3D);
		topFrameRotateTrnsGrp = new TransformGroup(topFrameRotateT3D);
	}

	private void initializeAddressFrameLayout()
	{
		currentAddressBoxTranslateT3D = new Transform3D();
		currentAddressTextTranslateT3D = new Transform3D();
		currentAddressTextScaleT3D = new Transform3D();

		currentAddressBoxTranslateT3D.setTranslation(new Vector3f(-3.0f, 0.8f, 0.0f));
		
		currentAddressTextScaleT3D.setScale(3.0);
		
		
		
		currentAddressBoxTranslateTrnsGrp = new TransformGroup(
				currentAddressBoxTranslateT3D);

		currentAddressTextScaleTrnsGrp = new TransformGroup(currentAddressTextScaleT3D);

		currentAddressTextTranslateTrnsGrp = new TransformGroup(
				currentAddressTextTranslateT3D);
		currentAddressTextTranslateTrnsGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		currentAddressTextTranslateTrnsGrp.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

		
	}

	private void initializeTransferProgressFrameLayout()
	{
		transferProgressBoxTranslateT3D = new Transform3D();
		transferProgressBoxTranslateT3D.setTranslation(new Vector3f(-3.0f, -0.21f, 0.0f));
		
		currentFileTextTranslateT3D = new Transform3D();
		currentFileTextScaleT3D = new Transform3D();
		
		progressBarTranslateT3D = new Transform3D();
		progressBarScaleT3D = new Transform3D();
		progressBarRotateT3D = new Transform3D();

		cancelButtonTranslateT3D = new Transform3D();
		cancelButtonScaleT3D = new Transform3D();
		cancelButtonRotateT3D = new Transform3D();

		
		currentFileTextScaleT3D.setScale(3.0);
		currentFileTextTranslateT3D.setTranslation(new Vector3f(-3.0f, 0.12f, 0.0f));
		
		cancelButtonTranslateT3D.setTranslation(new Vector3f(2.8f, -0.5f, 0.0f));
//		cancelButtonScaleT3D.rotX(-Math.PI/11.0);
		cancelButtonScaleT3D.setScale(0.8);

		
		progressBarTranslateT3D.setTranslation(new Vector3f(-1.0f, -0.5f, 0.0f));
		progressBarRotateT3D.rotX(-Math.PI/11.0);
		progressBarScaleT3D.setScale(5.0);
		
		
		transferProgressBoxTranslateTrnsGrp = new TransformGroup(
				transferProgressBoxTranslateT3D);
		
		
		currentFileTextTranslateTrnsGrp = new TransformGroup(currentFileTextTranslateT3D);
		currentFileTextScaleTrnsGrp = new TransformGroup(currentFileTextScaleT3D);
		
		currentFileTextScaleTrnsGrp.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
		currentFileTextScaleTrnsGrp.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
		
		cancelButtonTranslateTrnsGrp = new TransformGroup(cancelButtonTranslateT3D);
		cancelButtonRotateTrnsGrp = new TransformGroup(cancelButtonRotateT3D);
		cancelButtonScaleTrnsGrp = new TransformGroup(cancelButtonScaleT3D);
		cancelButtonScaleTrnsGrp.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
		cancelButtonScaleTrnsGrp.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
		
		progressBarTranslateTrnsGrp = new TransformGroup(progressBarTranslateT3D);
		
		progressBarRotateTrnsGrp = new TransformGroup(
				progressBarRotateT3D);
		
		progressBarScaleTrnsGrp = new TransformGroup(
				progressBarScaleT3D);
		
		progressBarScaleTrnsGrp.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
		progressBarScaleTrnsGrp.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
	}

	private void initializeClipboardFrameLayout()
	{
		clipboardBoxTranslateT3D = new Transform3D();
		clipboardBoxTranslateT3D.setTranslation(new Vector3d(2,0.0f,0.0f));
//		clipboardBoxTranslateT3D.setScale(new Vector3d(1,0.99,topFrameBox.getZdimension()));
		clipboardBoxTranslateTrnsGrp = new TransformGroup(clipboardBoxTranslateT3D);
		clipboardBoxTranslateTrnsGrp.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
		clipboardBoxTranslateTrnsGrp.setTransform(clipboardBoxTranslateT3D);
	}


	@Override
	protected void constructComponentGUIBranch()
	{

		
		/**
		 * >> Level 8
		 */
		
		//Detachable/Initially detached
		currentFileTextBrnchGrp.addChild(currentFileText2D);
		
		
		
		
		/**
		 * >> Level 7
		 */
		currentAddressTextScaleTrnsGrp.addChild(currentAddressText2D);
		
		progressBarRotateTrnsGrp.addChild(progressBarScaleTrnsGrp);
		cancelButtonRotateTrnsGrp.addChild(cancelButtonScaleTrnsGrp);
		/**
		 * >> Level 6
		 */
		currentAddressTextTranslateTrnsGrp.addChild(currentAddressTextScaleTrnsGrp);
		
		currentFileTextTranslateTrnsGrp.addChild(currentFileTextScaleTrnsGrp);
		
		progressBarTranslateTrnsGrp.addChild(progressBarRotateTrnsGrp);
		cancelButtonTranslateTrnsGrp.addChild(cancelButtonRotateTrnsGrp);
		
		/**
		 * >> Level 5
		 */

//		OrderedGroup orderedGroup = new OrderedGroup();
//		orderedGroup.addChild(currentAddressBox);
//		orderedGroup.addChild(currentAddressTextTranslateTrnsGrp);
//		currentAddressBoxTranslateTrnsGrp.addChild(orderedGroup);
		
		clipboardBoxTranslateTrnsGrp.addChild(clipboardBox);
		currentAddressBoxTranslateTrnsGrp.addChild(currentAddressBox);
		currentAddressBoxTranslateTrnsGrp.addChild(currentAddressTextTranslateTrnsGrp);
		
		transferProgressBoxTranslateTrnsGrp.addChild(transferProgressBox);
		transferProgressBoxTranslateTrnsGrp.addChild(progressBarTranslateTrnsGrp);
		transferProgressBoxTranslateTrnsGrp.addChild(cancelButtonTranslateTrnsGrp);
		transferProgressBoxTranslateTrnsGrp.addChild(currentFileTextTranslateTrnsGrp);
//		clipboardBoxTranslateTrnsGrp.addChild(clipboardBox);
		
		/**
		 * >> Level 4
		 */
//		topFrameRotateTrnsGrp.addChild(topFrameBox);
		topFrameRotateTrnsGrp.addChild(currentAddressBoxTranslateTrnsGrp);
		topFrameRotateTrnsGrp.addChild(transferProgressBoxTranslateTrnsGrp);
		topFrameRotateTrnsGrp.addChild(clipboardBoxTranslateTrnsGrp);
		/**
		 * >> Level 3
		 */
		topFrameScaleTrnsGrp.addChild(topFrameRotateTrnsGrp);
		/**
		 * >> Level 1
		 */
		topFrameTranslateTrnsGrp.addChild(topFrameScaleTrnsGrp);
		
		/**
		 * >> Level 0
		 */
		baseBrnchGrp.addChild(topFrameTranslateTrnsGrp);
		baseBrnchGrp.compile();
	}


	@Override
	public void augmentComponentGUIBranch(J3DComponent component)
	{
		HeadsUpDisplay headsUpDisplay = (HeadsUpDisplay)component;
		
		this.progressBarBrnchGrp = headsUpDisplay.getProgressBar();
		this.cancelButtonBrnchGrp = headsUpDisplay.getCancelButton();
		
		clipboardBoxTranslateTrnsGrp.addChild(headsUpDisplay.getClipboardContentsViewer());
	
		if(headsUpDisplay.getModel().isShowProgress())
		{
			showProgressComponents();
		}
	}
	
	private void showProgressComponents()
	{
		if(progressBarBrnchGrp.getParent() == null)
			progressBarScaleTrnsGrp.addChild(progressBarBrnchGrp);
		if(cancelButtonBrnchGrp.getParent() == null)
			cancelButtonScaleTrnsGrp.addChild(cancelButtonBrnchGrp);
		if(currentFileTextBrnchGrp.getParent() == null)
			currentFileTextScaleTrnsGrp.addChild(currentFileTextBrnchGrp);
	}
	
	private void hideProgressComponents()
	{
		progressBarScaleTrnsGrp.removeChild(progressBarBrnchGrp);
		cancelButtonScaleTrnsGrp.removeChild(cancelButtonBrnchGrp);
		currentFileTextScaleTrnsGrp.removeChild(currentFileTextBrnchGrp);
	}

	
	@Override
	public void render3DComponent(J3DComponent component)
	{
		HeadsUpDisplay headsUpDisplay = (HeadsUpDisplay)component;

		HeadsUpDisplayModel model = headsUpDisplay.getModel();

		if(model.getCurrentAddress() != null)
		{
			currentAddressText2D.setString(model.getCurrentAddress());
			
			J3DUIHelper.prepareLeftAlignedText2DTransform(headsUpDisplay.getCanvas3D(), 
					currentAddressTextFont, currentAddressText2D, currentAddressTextTranslateT3D, 
					 3.7f, currentAddressBox.getZdimension(), (float)currentAddressTextScaleT3D.getScale());
			currentAddressTextTranslateTrnsGrp.setTransform(currentAddressTextTranslateT3D);
		}
		
		if(model.isShowProgress())
		{
			if(model.getCurrentFile() != null)
			{
				currentFileText2D.setString(model.getCurrentFile());
			}
			
			showProgressComponents();
		}
		else
		{
			hideProgressComponents();
		}
	}

}
